package com.scale.service.voice.service.impl;

import com.scale.service.voice.service.VoiceFileStorageService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.UUID;

/**
 * 语音文件存储服务实现类
 * @author crp
 * @since 2025-09-24
 */
@Service
public class VoiceFileStorageServiceImpl implements VoiceFileStorageService {

    /**
     * 🔧 语音文件存储的绝对路径，从配置文件读取
     * 与VoiceFileController保持一致的默认值
     */
    @Value("${voice.storage.base-path:D:/programme/javaEE/scale/data/voice}")
    private String basePath;

    /**
     * 🔧 语音文件访问的基础URL，从配置文件读取
     */
    @Value("${voice.storage.base-url:http://localhost:8080/voice}")
    private String baseUrl;

    @Override
    public String storeVoiceFile(String audioData, String format, Long messageId) {
        try {
            // 解码Base64音频数据
            byte[] audioBytes;
            if (audioData.startsWith("data:audio")) {
                // 处理data URL格式
                String base64Data = audioData.substring(audioData.indexOf(',') + 1);
                audioBytes = Base64.getDecoder().decode(base64Data);
            } else {
                // 直接Base64编码的数据
                audioBytes = Base64.getDecoder().decode(audioData);
            }

            // 🔧 生成唯一文件名（一次性生成，确保一致性）
            String fileName = generateFileName(messageId, format);
            String relativePath = getRelativePath(fileName);
            String fullPath = basePath + File.separator + relativePath;
            
            // 🔧 先生成访问URL，确保与实际存储路径一致
            String accessUrl = baseUrl + "/" + relativePath.replace(File.separator, "/");
            
            System.out.println("🎵 文件存储详情:");
            System.out.println("   - 文件名: " + fileName);
            System.out.println("   - 相对路径: " + relativePath);
            System.out.println("   - 完整路径: " + fullPath);
            System.out.println("   - 访问URL: " + accessUrl);

            // 确保目录存在
            Path parentPath = Paths.get(fullPath).getParent();
            if (!Files.exists(parentPath)) {
                Files.createDirectories(parentPath);
                System.out.println("✅ 创建目录: " + parentPath);
            }

            // 写入文件
            try (FileOutputStream fos = new FileOutputStream(fullPath)) {
                fos.write(audioBytes);
            }
            
            // 验证文件是否存在
            File savedFile = new File(fullPath);
            if (savedFile.exists()) {
                System.out.println("✅ 文件保存成功: " + fullPath + ", 大小: " + savedFile.length() + " 字节");
            } else {
                System.err.println("❌ 文件保存失败: " + fullPath);
            }

            // 返回访问URL
            return accessUrl;

        } catch (Exception e) {
            throw new RuntimeException("存储语音文件失败: " + e.getMessage(), e);
        }
    }

    @Override
    public String storeVoiceFile(MultipartFile file, Long messageId) {
        try {
            // 获取文件扩展名
            String originalFilename = file.getOriginalFilename();
            String format = originalFilename != null ? 
                originalFilename.substring(originalFilename.lastIndexOf('.') + 1) : "wav";

            // 生成文件路径
            String fileName = generateFileName(messageId, format);
            String relativePath = getRelativePath(fileName);
            String fullPath = basePath + File.separator + relativePath;

            // 确保目录存在
            Path parentPath = Paths.get(fullPath).getParent();
            if (!Files.exists(parentPath)) {
                Files.createDirectories(parentPath);
            }

            // 保存文件
            file.transferTo(new File(fullPath));

            // 返回访问URL
            return baseUrl + "/" + relativePath.replace(File.separator, "/");

        } catch (Exception e) {
            throw new RuntimeException("存储上传语音文件失败: " + e.getMessage(), e);
        }
    }

    @Override
    public boolean deleteVoiceFile(String fileUrl) {
        try {
            String relativePath = fileUrl.replace(baseUrl + "/", "").replace("/", File.separator);
            String fullPath = basePath + File.separator + relativePath;
            
            File file = new File(fullPath);
            return file.exists() && file.delete();
        } catch (Exception e) {
            System.err.println("删除语音文件失败: " + e.getMessage());
            return false;
        }
    }

    @Override
    public String getLocalPath(String fileUrl) {
        String relativePath = fileUrl.replace(baseUrl + "/", "").replace("/", File.separator);
        return basePath + File.separator + relativePath;
    }

    /**
     * 生成文件名
     */
    private String generateFileName(Long messageId, String format) {
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String prefix = messageId != null ? "msg_" + messageId + "_" : "";
        return prefix + uuid + "." + format;
    }

    /**
     * 生成用户录音文件名 (按前端需求格式)
     */
    private String generateUserFileName(Long userId, String format) {
        long timestamp = System.currentTimeMillis();
        return String.format("user_%d_%d.%s", timestamp, userId, format);
    }

    /**
     * 生成相对路径（按日期分目录）
     */
    private String getRelativePath(String fileName) {
        String dateDir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        return dateDir + File.separator + fileName;
    }

    /**
     * 生成用户录音相对路径（按前端需求）
     */
    private String getUserRelativePath(String fileName) {
        return "user" + File.separator + fileName;
    }

    @Override
    public String storeUserVoiceFile(String audioData, String format, Long userId) {
        try {
            // 解码Base64音频数据
            byte[] audioBytes;
            if (audioData.startsWith("data:audio")) {
                // 处理data URL格式
                String base64Data = audioData.substring(audioData.indexOf(',') + 1);
                audioBytes = Base64.getDecoder().decode(base64Data);
            } else {
                // 直接Base64编码的数据
                audioBytes = Base64.getDecoder().decode(audioData);
            }

            // 生成用户录音文件名 (按前端需求格式)
            String fileName = generateUserFileName(userId, format);
            String relativePath = getUserRelativePath(fileName);
            String fullPath = basePath + File.separator + relativePath;

            // 确保目录存在
            Path parentPath = Paths.get(fullPath).getParent();
            if (!Files.exists(parentPath)) {
                Files.createDirectories(parentPath);
            }

            // 写入文件
            try (FileOutputStream fos = new FileOutputStream(fullPath)) {
                fos.write(audioBytes);
            }

            // 返回访问URL
            return baseUrl + "/" + relativePath.replace(File.separator, "/");

        } catch (Exception e) {
            throw new RuntimeException("存储用户录音文件失败: " + e.getMessage(), e);
        }
    }
}
